Skip to content

Align have_relationship matcher with readme and add support for Symbol or String parameters #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from

Conversation

sa73917
Copy link
Contributor

@sa73917 sa73917 commented Jun 9, 2020

What is the current behavior?

The current README file provides an example usage for the matcher of

  • expect(document['data']).to have_relationships(:posts, :comments)
    With the current implementation of have_relationships, this fails as it does not to_s the relationship array values provided.

PR #15 was rejected as it only added Symbol parameters to the relationships matcher without updating all matchers.

This PR includes support for symbol parameters in all matchers

What is the new behavior?

All matchers now accept strings or symbols (and string or symbol keyed hashes where applicable)
Relationships matcher now has a spec to test it.

Checklist

Please make sure the following requirements are complete:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes /
    features)
  • All automated checks pass (CI/CD)

@sa73917 sa73917 force-pushed the sanderson/symbol_params branch 2 times, most recently from 1fd1c91 to 2859c6f Compare June 9, 2020 02:04
sa73917 added 7 commits June 9, 2020 12:12
Added enabled: true for all new cops to remove warnings about then when running rubocop.  Added ignore for block length to specs directory as many specs blocks are longer than the maximum.
Create .rspec file to remove the need to require spec_helper in all specs.
…arameters).

The current README file provides an example usage for the matcher of 
* `expect(document['data']).to have_relationships(:posts, :comments)`

With the current implementation of have_relationships, this fails as it does not to_s the relationship array values provided.  Minor fix to correct this.
Add support for symbol keyed hashes to the have_jsonapi_object matcher and create related spec tests.
Add support for symbol keyed hashes to the have_meta matcher and create related spec tests.
Add support for symbol keyed hashes to the have_relationship matcher and create related spec tests.
@sa73917 sa73917 force-pushed the sanderson/symbol_params branch from 2859c6f to 8a0720e Compare June 9, 2020 02:14
sa73917 added 2 commits June 10, 2020 17:28
Add support for using a symbol as the type and create related spec tests.
For consistency, as all other specs now contain tests for symbols and strings, added string tests into the attributes and links specs.
@sa73917 sa73917 force-pushed the sanderson/symbol_params branch from 8a0720e to 265d2ed Compare June 10, 2020 07:29
@sa73917 sa73917 marked this pull request as draft June 10, 2020 07:31
@sa73917 sa73917 marked this pull request as ready for review June 10, 2020 07:32
@sa73917 sa73917 changed the title Align have_relationship matcher with readme and add support for symbol or string parameters (including hash keys) for all matchers Align have_relationship matcher with readme and add support for symbol or string parameters Jun 12, 2020
@sa73917 sa73917 changed the title Align have_relationship matcher with readme and add support for symbol or string parameters Align have_relationship matcher with readme and add support for Symbol or String parameters Jun 12, 2020
@stas
Copy link
Collaborator

stas commented Jun 29, 2020

Superseded by #18

@stas stas closed this Jun 29, 2020
@stas
Copy link
Collaborator

stas commented Jun 29, 2020

@sa73917 I went ahead and cherry-picked your work. Unfortunately I had to revert the changes you did on the tests, please review the relevant commit and let me know if you have questions why the rest of the work was not included b6085bc

Thanks again for helping with this.

@sa73917 sa73917 deleted the sanderson/symbol_params branch June 29, 2020 13:10
@sa73917
Copy link
Contributor Author

sa73917 commented Jul 13, 2020

@stas - just looking at what eventually went into master - the aim of this PR was to allow all the
matchers to accept parameters that are strings or symbols. (as in it's current state, some accept symbols (have_attribute, have_relationship) and some don't (have_type). In my code I covered all the matchers but my main driver was allowing the have_type matcher to accept symbols. It looks like after your changes before the merge this logic was removed. Was this by design or an oversight?

@stas
Copy link
Collaborator

stas commented Jul 13, 2020

@sa73917 I'm taking a second look and I don't think I follow.

Mainly, it does look like have_attributeand have_relationship are allowing strings/symbols and are not strict, which I agree should not be allowed. But I don't see how this PR solves this.

I'll be happy to merge the fix if you can open another PR that does not allow symbols and strings to match attributes and relationships in the same time though.

Sorry for missing out on the initial issue that was raised. 🙈

@sa73917
Copy link
Contributor Author

sa73917 commented Jul 15, 2020

Sounds like your change to the code in my PR was intentional then (which is unfortunate IMO).

Whilst I understand a true JSON document can't have symbols in it, at the end of the day this is a Ruby gem that helps test JSON documents so (at least from my point of view) it should allow ruby developers to use it much like they would expect to interact with the vast majority of ruby gems (and in fact most standard ruby methods and objects)

Clearly personal opinion but I'd much prefer to read:

expect(document[:data]).to have_type(:users)

rather than:

expect(document['data']).to have_type('users')

My expectation when passing symbols into the matcher is (obviously) not that the type attribute will have a symbol as its value (as that would be impossible). I'm just expecting the matcher will include a "to_s" on their expected type. Eg.

module JSONAPI
  module RSpec
    module Type
      ::RSpec::Matchers.define :have_type do |expected|
        match do |actual|
          JSONAPI::RSpec.as_indifferent_hash(actual)['type'] == expected.to_s
        end
      end
    end
  end
end

Oh well, if you change your mind and would like a PR that ensures all the matchers will accept symbols, I'm more than happy to do so. I'll respectfully decline the reverse however, as I'm loath to remove the symbol parameter functionality from the matchers that already accept them - I'd have to change a bunch of my specs into a format I much less prefer to read. :-)

@stas
Copy link
Collaborator

stas commented Jul 15, 2020

I think we should make it clear that without jsonapi_indifferent_hash the matchers will be dumb and match documents only based on the user implementation. For example, if you are testing hashes with symbols as keys, and trying to match against a string key, tests won't pass.

And only if you set up jsonapi_indifferent_hash = true the above will ignored, such that the hashes can match either with a string or a symbol.

I think the default behaviour is valid only for folks who really want to encourage a specific way of formatting the tests/jsonapi-documents, but for the most of the users, jsonapi_indifferent_hash = true should be more than enough.

Let me know if that makes sense. And I would definitely not mind updating those two matchers that force the string-based matching.

Thank you for clarifying this @sa73917!

@sa73917
Copy link
Contributor Author

sa73917 commented Jul 15, 2020

No worries - always hard to understand intent in text isn't it! :-)

If we are to go down the path of the the jsonapi_indifferent_hash configuration flag being the driver for this, then we should update the existing matchers to reflect this change too.. So with it true - it's whatever combination of strings and symbols you feel like (in the source document and matcher parameters).. with it false, it's strings only everywhere..

Is that what you're thinking?

@stas
Copy link
Collaborator

stas commented Jul 16, 2020

Is that what you're thinking?

Nope. What I'm trying to say is that... If you're trying to use the matchers on a document like this with strings:

{
  data: {
    attributes: {
      id: "1",
      email: "my@domain.tld"
    }
  }
}

it should fail, and succeed on symbols (since obviously the document uses symbols (likewise with the opposite: string keys, and trying to match with symbol names).

If you have enabled the jsonapi_indifferent_hash it will pass since we don't care what keys are being used.

Basically, I don't want us to alter the document/matcher arguments, unless we are explicitly told jsonapi_indifferent_hash = true.

@sa73917
Copy link
Contributor Author

sa73917 commented Jul 17, 2020

I think we're in violent agreement on the true setting

with jsonapi_indifferent_hash set to true - it should work with whatever combination of symbols and strings you feel like throwing at it. Symbolized or string source document matching happily with symbolized or string based parameters.

On the false setting though - my thought was assume the source must be a valid JSON document and hence parameters must be strings. Sounds like you'd like to leave source and parameters alone and just compare directly. So if it's a symbolized source document, it should only match symbolized parameters. If it's a string source document it should only match string parameters.

Do I have it now? :)

@stas
Copy link
Collaborator

stas commented Jul 17, 2020

On the false setting though - my thought was assume the source must be a valid JSON document and hence parameters must be strings. Sounds like you'd like to leave source and parameters alone and just compare directly. So if it's a symbolized source document, it should only match symbolized parameters. If it's a string source document it should only match string parameters.

I'm afraid this can still be confusing since we'd have to convert to strings for have_meta as well (see #17 for example). So I really believe we should not touch/alter the original document or matcher arguments or folks won't like us at all! 🙈

@sa73917
Copy link
Contributor Author

sa73917 commented Jul 19, 2020

Rather than go back and forth trying to describe this - here's a branch with my suggested change. At a high level, it basically means each matcher calls as_indifferent_hash on the user supplied keys and (for the value matchers), on the user supplied values.

(I did think it might be worth having a jsonapi_indifferent_parameters configuration option (and related as_indifferent_param) method so the users can have control of whether source, parameters or both are processed to be indifferent but figured it's a minor change from where this branch is if you think its worth it..

@stas
Copy link
Collaborator

stas commented Jul 30, 2020

@sa73917 I went ahead and made it clear that we will always convert matcher arguments where JSON:API spec dictates the format.

I'm considering this conversation resolved for now. Thank you for helping with it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants